<?php
namespace Hphp\Foundation;

use Hphp\Container\Container;
use Hphp\Event\Event;

class Application extends Container
{
    protected $basePath;
    protected $serviceProviders;
    protected $booted = false;

    public function __construct($basePath = null)
    {
        // 设置项目地址
        if ($basePath) {
            $this->setBasePath($basePath);
        }

        // 注册核心的应用到容器中
        $this->registerBaseBindings();

        // 注册核心的应用服务提供者
        // 注册：事件，日志，路由
        $this->registerBaseServiceProviders();
        // 注册应用容器别名
        $this->registerCoreContainerAliases();

        //\Hphp\Support\Facades\Facade::setFacadeApplication($this);
    }

    public function registerBaseBindings()
    {
        // 设置自己为单例实例对象
        static::setInstance($this);

        $this->instance('app', $this);
    }

    public function registerBaseServiceProviders()
    {
        // event;
        // 这是一种low一点写法

        $event = new Event($this);

        // 通过扫描指定目录下的类名
        // 然后再根据相应的命名空间，加载执行
        // 注册到事件中

        $files = scandir($this->getBasePath().'/app/Listeners');

        // 2. 读取文件信息
        foreach ($files as $key => $file) {
            if ($file === '.' || $file === '..') {
                continue;
            }

            $class = 'App\\Listeners\\'.\explode('.', $file)[0];
            // dd($class);
            if (\class_exists($class)) {
                $listener = new $class($this);
                $event->listener($listener->getName(), [$listener, 'handler']);
            }
        }

        $this->instance('events', $event);
    }

    public function boot()
    {
        // 对于应用来说事先执行
        if ($this->booted) {
            return ;
        }

        foreach ($this->serviceProviders as $key => $provider) {
            if (\method_exists($provider, 'boot')) {
                $provider->boot();
            }
        }

        $this->booted = true;
    }

    /*
    * 根据配制注册服务提供者
    */
    public function registerConfiguredProviders()
    {
        $privoders = $this->make('config')->get('app.provider');

        (new ProviderRegister($this))->load($privoders);
    }

    /**
     * 记录解析的服务提供者
     */
    public function marASRegistered($provider)
    {
        $this->serviceProviders[] = $provider;
    }

    // -------------- 设置框架项目地址 ----------------
    public function setBasePath($path)
    {
        $this->basePath = rtrim($path, '\/');
    }

    public function getBasePath()
    {
        return $this->basePath;
    }

    public function registerCoreContainerAliases()
    {
        $binds = [
            'cookie' => \Hphp\Cookie\Cookie::class,
            'config' => \Hphp\Config\Config::class,
            'db'     => \Hphp\Databases\MySql::class,
            'route'  => \Hphp\Router\Router::class,
            // 'db' => [
            //   \Hphp\Databases\Oracle::class,
            //   \Hphp\Contracts\Databases\Db::class
            // ],
            // \Hphp\Contracts\Databases\Db::class => \LaravelStar\Databases\Oracle::class
            // ..
        ];
        foreach ($binds as $key => $bind) {
            $this->bind($key, $bind);
        }
    }

    public function bootstrapWith(array $bootstrappers)
    {
        // $this->hasBeenBootstrapped = true;

        foreach ($bootstrappers as $bootstrapper) {
            $this->make($bootstrapper)->bootstrap($this);
        }
    }
}